home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-ALPH.{_4 / SOFTIRQ.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  2KB  |  130 lines

  1. #ifndef _ALPHA_SOFTIRQ_H
  2. #define _ALPHA_SOFTIRQ_H
  3.  
  4. #include <linux/stddef.h>
  5. #include <asm/atomic.h>
  6. #include <asm/hardirq.h>
  7.  
  8. extern unsigned int local_bh_count[NR_CPUS];
  9.  
  10. #define get_active_bhs()    (bh_mask & bh_active)
  11.  
  12. static inline void clear_active_bhs(unsigned long x)
  13. {
  14.     unsigned long temp;
  15.     __asm__ __volatile__(
  16.     "1:    ldq_l %0,%1\n"
  17.     "    bic %0,%2,%0\n"
  18.     "    stq_c %0,%1\n"
  19.     "    beq %0,2f\n"
  20.     ".section .text2,\"ax\"\n"
  21.     "2:    br 1b\n"
  22.     ".previous"
  23.     :"=&r" (temp), "=m" (bh_active)
  24.     :"Ir" (x), "m" (bh_active));
  25. }
  26.  
  27. extern inline void init_bh(int nr, void (*routine)(void))
  28. {
  29.     bh_base[nr] = routine;
  30.     atomic_set(&bh_mask_count[nr], 0);
  31.     bh_mask |= 1 << nr;
  32. }
  33.  
  34. extern inline void remove_bh(int nr)
  35. {
  36.     bh_base[nr] = NULL;
  37.     bh_mask &= ~(1 << nr);
  38. }
  39.  
  40. extern inline void mark_bh(int nr)
  41. {
  42.     set_bit(nr, &bh_active);
  43. }
  44.  
  45. #ifdef __SMP__
  46.  
  47. /*
  48.  * The locking mechanism for base handlers, to prevent re-entrancy,
  49.  * is entirely private to an implementation, it should not be
  50.  * referenced at all outside of this file.
  51.  */
  52. extern atomic_t global_bh_lock;
  53. extern atomic_t global_bh_count;
  54.  
  55. extern void synchronize_bh(void);
  56.  
  57. static inline void start_bh_atomic(void)
  58. {
  59.     atomic_inc(&global_bh_lock);
  60.     synchronize_bh();
  61. }
  62.  
  63. static inline void end_bh_atomic(void)
  64. {
  65.     atomic_dec(&global_bh_lock);
  66. }
  67.  
  68. /* These are for the irq's testing the lock */
  69. static inline int softirq_trylock(int cpu)
  70. {
  71.     if (!test_and_set_bit(0,&global_bh_count)) {
  72.         if (atomic_read(&global_bh_lock) == 0) {
  73.             ++local_bh_count[cpu];
  74.             return 1;
  75.         }
  76.         clear_bit(0,&global_bh_count);
  77.     }
  78.     return 0;
  79. }
  80.  
  81. static inline void softirq_endlock(int cpu)
  82. {
  83.     local_bh_count[cpu]--;
  84.     clear_bit(0,&global_bh_count);
  85. }
  86.  
  87. #else
  88.  
  89. extern inline void start_bh_atomic(void)
  90. {
  91.     local_bh_count[smp_processor_id()]++;
  92.     barrier();
  93. }
  94.  
  95. extern inline void end_bh_atomic(void)
  96. {
  97.     barrier();
  98.     local_bh_count[smp_processor_id()]--;
  99. }
  100.  
  101. /* These are for the irq's testing the lock */
  102. #define softirq_trylock(cpu) \
  103.   (local_bh_count[cpu] ? 0 : (local_bh_count[cpu] = 1))
  104.  
  105. #define softirq_endlock(cpu) \
  106.   (local_bh_count[cpu] = 0)
  107.  
  108. #define synchronize_bh()    do { } while (0)
  109.  
  110. #endif    /* SMP */
  111.  
  112. /*
  113.  * These use a mask count to correctly handle
  114.  * nested disable/enable calls
  115.  */
  116. extern inline void disable_bh(int nr)
  117. {
  118.     bh_mask &= ~(1 << nr);
  119.     atomic_inc(&bh_mask_count[nr]);
  120.     synchronize_bh();
  121. }
  122.  
  123. extern inline void enable_bh(int nr)
  124. {
  125.     if (atomic_dec_and_test(&bh_mask_count[nr]))
  126.         bh_mask |= 1 << nr;
  127. }
  128.  
  129. #endif /* _ALPHA_SOFTIRQ_H */
  130.